﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace MissionEditor
{
    public class Mission
    {
        #region Statics
        private static string[] units = {
                                "Light Infantry",
                                "Trooper",
                                "Engineer",
                                "Thumper",
                                "Sardaukar",
                                "Trike",
                                "Raider",
                                "Quad",
                                "Harvester",
                                "A Combat Tank",
                                "H Combat Tank",
                                "O Combat Tank",
                                "MCV",
                                "Missile Tank",
                                "Deviator",
                                "Seige Tank",
                                "Sonic Tank",
                                "Devastator",
                                "Carryall",
                                "A Carryall",
                                "Ornithopter (useless)",
                                "Stealth Fremen",
                                "Fremen",
                                "Saboteur",
                                "Death Hand Missle",
                                "Glitched Unit",
                                "Frigate (starport)",
                                "Grenadier",
                                "Stealth Raider",
                                "MP Sardaukar"
                             };
        private static string[] buildings = {
                                "Atreides Construction Yard",
                                "Harkonnen Construction Yard",
                                "Ordos Construction Yard",
                                "Imperial Construction Yard",
                                "Atreides Concrete",
                                "Harkonnen Concrete",
                                "Ordos Concrete",
                                "Atreides Test Concrete",
                                "Harkonnen Test Concrete",
                                "Ordos Test Concrete",
                                "Atreides Wind Trap",
                                "Harkonnen Wind Trap",
                                "Ordos Wind Trap",
                                "Atreides Barracks",
                                "Harkonnen Barracks",
                                "Ordos Barracks",
                                "Fremen Barracks",
                                "Atreides Wall",
                                "Harkonnen Wall",
                                "Ordos Wall",
                                "Atreides Refinery",
                                "Harkonnen Refinery",
                                "Ordos Refinery",
                                "Atreides Medium Gun Turret",
                                "Harkonnen Medium Gun Turret",
                                "Ordos Medium Gun Turret",
                                "Atreides Outpost",
                                "Harkonnen Outpost",
                                "Ordos Outpost",
                                "Atreides Large Gun Turret",
                                "Harkonnen Large Gun Turret",
                                "Ordos Large Gun Turret",
                                "Atreides High Tech Factory",
                                "Harkonnen High Tech Factory",
                                "Ordos High Tech Factory",
                                "Atreides Light Factory",
                                "Harkonnen Light Factory",
                                "Ordos Light Factory",
                                "Atreides Silo",
                                "Harkonnen Silo",
                                "Ordos Silo",
                                "Atreides Heavy Factory",
                                "Harkonnen Heavy Factory",
                                "Ordos Heavy Factory",
                                "Mercenary Heavy Factory",
                                "Imperial Heavy Factory",
                                "Atreides Star Port",
                                "Harkonnen Star Port",
                                "Ordos Star Port",
                                "Smuggler Star Port",
                                "Atreides Repair Pad",
                                "Harkonnen Repair Pad",
                                "Ordos Repair Pad",
                                "Atreides Research Centre",
                                "Harkonnen Research Centre",
                                "Ordos Research Centre",
                                "Atreides Palace",
                                "Harkonnen Palace",
                                "Ordos Palace",
                                "Imperial Palace",
                                "Special Harkonnen Outpost",
                                "Special Ordos Outpost"
                            };

        public static string[] Units { get { return units; } }
        public static string[] Buildings { get { return buildings; } } 
        #endregion

        public byte[] houseTechLevel = new byte[8];
        public Int32[] startingMoney = new Int32[8];
        public byte[] unknownRegion1 = new byte[40];
        public byte[] houseIndexAllocation = new byte[8];
        public byte[,] ai = new byte[8, 7608];
        public byte[,] diplomacy = new byte[8, 8];
        public Event[] events = new Event[64];
        public Condition[] conditions = new Condition[48];
        public byte[] tilesetImageName = new byte[200];
        public byte[] tilesetDataName = new byte[200];
        public byte eventCount;
        public byte conditionCount;        
        public Int32 timeLimit;
        public byte[] unknownRegion4 = new byte[692];

        

        public void LoadFromFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open);
            BinaryReader br = new BinaryReader(fs);

            br.Read(houseTechLevel, 0, houseTechLevel.Length);

            for (int i = 0; i < startingMoney.Length; i++)
            {
                startingMoney[i] = br.ReadInt32();
            }

            br.Read(unknownRegion1, 0, unknownRegion1.Length);
            br.Read(houseIndexAllocation, 0, houseIndexAllocation.Length);

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 7608; j++)
                {
                    ai[i, j] = br.ReadByte();
                }
            }
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    diplomacy[i, j] = br.ReadByte();
                }
            }

            for (int i = 0; i < events.Length; i++)
            {
                events[i] = new Event();
                events[i].raw = br.ReadBytes(72);
            }
            for (int i = 0; i < conditions.Length; i++)
            {
                conditions[i] = new Condition();
                conditions[i].raw = br.ReadBytes(28);
            }

            br.Read(tilesetImageName, 0, tilesetImageName.Length);
            br.Read(tilesetDataName, 0, tilesetDataName.Length);

            eventCount = br.ReadByte();
            conditionCount = br.ReadByte();
            timeLimit = br.ReadInt32(); // Signed
            br.Read(unknownRegion4, 0, unknownRegion4.Length);

            br.Close();
            fs.Close();
        }
        public void SaveToFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(houseTechLevel);

            for (int i = 0; i < startingMoney.Length; i++)
            {
                bw.Write(startingMoney[i]);
            }
            bw.Write(unknownRegion1);
            bw.Write(houseIndexAllocation);

            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 7608; j++)
                {
                    bw.Write(ai[i, j]);
                }
            }
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    bw.Write(diplomacy[i, j]);
                }
            }       

            for (int i = 0; i < events.Length; i++)
            {
                bw.Write(events[i].raw);
            }
            for (int i = 0; i < conditions.Length; i++)
            {
                bw.Write(conditions[i].raw);
            }

            bw.Write(tilesetImageName);
            bw.Write(tilesetDataName);

            bw.Write(eventCount);
            bw.Write(conditionCount);
            bw.Write(timeLimit);
            bw.Write(unknownRegion4);

            bw.Close();
            fs.Close();
        }
        public static string GetEventDescriptionFromIndex(int index)
        {
            switch (index)
            {
                case 0: return "Reinforcement";
                case 1: return "Starport Delivery";
                case 2: return "Diplomacy";
                case 4: return "Beserk";
                case 6: return "Unknown6";
                case 9: return "Related to first 50 bytes";
                case 10: return "Mission Win";
                case 11: return "Mission Fail";
                case 14: return "Reveal Map";
                case 15: return "Time Limit Related";
                case 16: return "Time Limit Disable";
                case 17: return "Message";
                case 18: return "Unit Spawn";
                case 19: return "Set Condition";
                default: return "Invalid Unknown";
            }

        }
        public static string GetConditionDescriptionFromIndex(int index)
        {
            switch (index)
            {
                case 0: return "BuildingExists";
                case 1: return "UnitExists";
                case 2: return "Interval";
                case 3: return "Timer";
                case 4: return "Casualties";
                case 5: return "BaseDestroyed";
                case 6: return "UnitsDestroyed";
                case 7: return "Unit In Tile";
                case 8: return "Cash";
                case 9: return "DummyCondition";
                default: return "Unknown";
            }
        }
        public static string GetUnitNameFromIndex(int index)
        {
            if (index >= 0 && index < units.Length)
                return units[index];
            else
                return "Invalid";
        }
    }
}
